package tripmaker

// mucha cosa está definida en los objectos compañeros de las clases
import Moneda._
import eventos._
import Comer._
import movimientos._
import Territorio._
import Lugar._
import Empresa._
import Dormir._
import Pais._
import Medio._
import Monto._
import Comer._

// la generación de los reportes HTML depende de este objeto
import tripmaker.output.HTML

/*
 * en general no tiene sentido tener más de una instancia de la 
 * planificación por lo que se ajusta bien usar un singleton
 */
object ViajeEjemplo extends Viaje {

  val nombre = "Viaje de Ejemplo"

  /* 
   * imágen que será usada en la portada del reporte que se genera
   * al ejecutar este objeto
   */
  val logo = "bolita.jpg"

  val origen = Montevideo

  /* 
   * se puede definir un costo base para las comidas que será usado
   * cada vez que se registre un evento "Comer()"
   * el trait MontoComer es para poder tener múltiples montos implícitos
   * que no generen ambigüedades.
   */
  implicit val CostoComer = new Monto(10, USD) with MontoComer

  /* 
   * idem para el costo del hospedaje. En ese caso se tiene un
   * estimado de lo que saldrá ($200000 CLP) y se lo divide
   * entra la cantidad de noches
   */ 
  val cantNoches = 26
  implicit val CostoDormir = new Monto(200000 / cantNoches, CLP) with MontoDormir

  // la lista de días planificados
  def dias = List(

    /* 
     * el trait "Viaje" define algunos métodos utilitarios 
     * para crear "días", ej. `fechab()()` es para un día que tiene 
     * planificados "eventos" pero no "actividades". la primera lista de 
     * argumentos es la fecha. la segunda lista de argumentos es una 
     * lista variable de eventos
     */ 
    fechab(año = 2011, mes = 6, día = 26)(

      /* 
       * registra que hay que desayunar :). normalmente registraría 
       * el costo implícito definido para las comidas pero en este 
       * caso se define costo cero explícitamente.
       */
      Comer()(CeroComer),

      // evento genérico para registrar el costo asociado
      Difuso("Taxi a aeropuerto")(Monto(500, UYU)),

      /* 
       * otro evento genérico, sin costo, estos los genera con un 
       * `checkbox` como para indicar que se cumplió je
       */
      Hito("Estar a 12:00 en Aeropuerto"),

      Difuso("Tasa de embarque")(Monto(36, USD)),

      /* 
       * salida. define una hora, un minuto, un Territorio de origen, 
       * un Lugar de origen, el Medio y el costo. 
       * Los territorios en general son objetos y definen algunos datos 
       * como el uso horario y el país.
       * Los lugares son más genéricos, puede identificar aeropuertos,
       * terminales terrestres etc.
       * El medio es más que nada para registrar la empresa por la que se
       * viaja y los datos del vuelo/bus/etc.
       */
      Salida(hora = 13, minuto = 47,
        desde = Montevideo, lugar = MVD,
        medio = Vuelo(LAN, "LA XXX"),
        costo = Cero),

      // marca el cambio de países para el reporte generado
      CruceFrontera(Santiago),

      // el evento comer puede tener "observaciones"
      Comer("en el avion")(CeroComer),

      // llegada. especifica la hora, el minuto, el territorio y el lugar
      Llegada(hora = 15, minuto = 30,
        a = Santiago, lugar = SCL),

      Difuso("/* otros eventos....*/")(Cero),

      /* 
       * sirve para marcar un cambio de territorio que no quedó
       * determinado por una salida o llegada
       */
      MarcaTerritorio(Coquimbo),

      Comer(),

      // usa el costo implícito del hospedaje
      Dormir()

    /* 
     * explorar paquete `tripmaker.eventos` para ver otros
     * eventos disponibles
     */
    ),

    /* 
     * otro de los métodos utilitarios es `fechan()` que sería para 
     * indicar que es un día de viaje para el que todavía no hay
     * un plan. registra tres "comer" y un "domir" usando los
     * costos implícitos :). tiene una lista de argumentos que sirve para
     * indicar año, mes y día pero son opcionales. si no se 
     * especifican se utiliza el día siguiente al anterior
     */
    fechan(),
    fechan(),
    fechan(),
    fechan(),
    /* 
     * el último de los métodos utilitarios para definir días es
     * `fecha()()()`. es el más general, permite definir la fecha,
     * los eventos y las actividades. los otros métodos se implementan
     * en función de este
     */
    fecha()(
      Comer(),

      Difuso("Taxi/óminus aeropuerto La serena")(Monto(25000, CLP)),

      Hito("Estar a 9:40 en Aeropuerto"),

      Difuso("Tasa de embarque?")(Monto(30, USD)),

      Salida(hora = 9, minuto = 23,
        desde = LaSerena, lugar = LSC,
        medio = Vuelo(LAN, "LA XXXX"),
        costo = Cero),

      Comer("en el avión")(CeroComer),

      Llegada(hora = 12, minuto = 40,
        a = Santiago, lugar = SCL),

      Difuso("/* ... eventos */")(Cero),

      Difuso("Taxi de vuelta")(Monto(500, UYU))
    )(
        /* 
         * hay algunos implicits en contexto, por ejemplo
         * este que permite convertir strings a actividades
         */
        "Aburrirse en los aeropuertos...",

        /*
         * si la actividad tiene "sub componentes" hay que 
         * usar una actividad explícitamente
         */
        Actividad("Alguna actividad con opciones",
          "* opción A",
          "* opción B")
      )
  )
  
  
  /* 
   * el trait Viaje define un método main, por lo tanto este objeto es
   * un ejecutable de Scala. por defecto lo que hace es imprimir un
   * resumen de costos y generar los reportes html en la carpeta 
   * `output` del proyecto. Por ejemplo para este viaje uno de los 
   * reportes que se genera es este:
   * https://trip-maker.googlecode.com/git/output/Viaje%20de%20Ejemplo.html
   */
  
}